/*
 *  AudioTrack.h
 *  SoundController0002
 *
 *  Created by jiro on 10/06/30.
 *  Copyright 2010 jiro music. All rights reserved.
 *
 */

#pragma once

#include "AudioElement.h"
#include "Constants.h"
#include <set>
#include <vector>

namespace sc 
{
	template< class AudioData >
	class AudioTrack 
	{
	protected:
	
		typedef typename std::multiset< AudioElement< AudioData > >::const_iterator AudioElementIter;

	protected:

		std::multiset< AudioElement< AudioData > > audioElements;

	public:

		void Record( double time, const SoundElement< AudioData >* soundElement )
		{
			audioElements.insert( AudioElement< AudioData >( time, soundElement ) );
		}
		
		void Record( const AudioElement< AudioData >& audioElement )
		{
			audioElements.insert( audioElement );
		}
		
		double GetDuration() const
		{
			double timeMax = 0;
			AudioElementIter iter = audioElements.begin();
			while ( iter != audioElements.end() )
			{
				double time = iter->GetStartTime() + iter->GetDuration();
				if ( time > timeMax )
				{
					timeMax = time;
				}
				iter++;
			}
			return timeMax;
		}
		
		void GetAudioData( std::vector< AudioData >& audioData ) const
		{
			double currentTime = 0;
			AudioElementIter iter = audioElements.begin();
			std::vector<AudioElementIter> queuedElements;
			const double duration = GetDuration();

			audioData.clear();

			while ( currentTime < duration )
			{
				while ( iter != audioElements.end() && iter->Contains( currentTime ) )
				{
					queuedElements.push_back( iter );
					iter++;
				}

				size_t count = queuedElements.size();
				double data = 0;
				for ( size_t i = 0; i < count; i++ )
				{
					data += queuedElements[ i ]->GetAudioData( currentTime );
				}
				audioData.push_back( data );

				currentTime += 1.0 / Sampling_Rate_As_Double;
				for ( size_t i = 0; i < queuedElements.size(); )
				{
					if ( queuedElements[ i ]->Contains( currentTime ) == false )
					{
						queuedElements.erase( queuedElements.begin() + i );
					}
					else 
					{
						i++;
					}
				}
			}
		}

	};
	
	typedef AudioTrack< float > AudioTrack32;
	
}
